/*
 * Proyecto fin de master. Servicio de alertas 112
 * Jorge Tarancon Iglesias
 * Master en desarrollo de aplicaciones para Internet y Moviles
 */
package es.us.mwm.sessionBean;

import es.us.mwm.entities.Users;
import java.util.List;
import javax.annotation.Resource;
import javax.ejb.SessionContext;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Clase para la persistencia de los usuarios. Se podria haber heredado de AbstracFacade para simplificar
 *
 * @author y0rg
 */
@Stateless
public class UserEJB implements UserEJBLocal {

    @Resource
    SessionContext sessionContext;

    @PersistenceContext
    private EntityManager em;

    /**
     * Metodo para acceder al atributo de clase
     *
     * @param em Manejador de entidades
     */
    public void setEm(EntityManager em) {
        this.em = em;
    }

    /**
     * Metodo para acceder al atributo de clase
     *
     * @return manejador de entidades
     */
    public EntityManager getEm() {
        return em;
    }

    /**
     * Contructor sin parametros
     */
    public UserEJB() {
    }

    /**
     * Metodo para obtener un rango de resultado de busqueda
     *
     * @param jpqlStmt
     * @param firstResult
     * @param maxResults
     * @return
     */
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public Object queryByRange(String jpqlStmt, int firstResult, int maxResults) {
        Query query = em.createQuery(jpqlStmt);
        if (firstResult > 0) {
            query = query.setFirstResult(firstResult);
        }
        if (maxResults > 0) {
            query = query.setMaxResults(maxResults);
        }
        return query.getResultList();
    }

    /**
     * Metodo para persistir una entidad
     *
     * @param <T> Tipo de entidad
     * @param entity entidad
     * @return entidad persistida
     */
    public <T> T persistEntity(T entity) {
        em.persist(entity);
        return entity;
    }

    /**
     * Metodo para editar/modificar una entidad, si no existe, la crea
     *
     * @param <T> Tipo de entidad
     * @param entity entidad
     * @return entidad editada
     */
    public <T> T mergeEntity(T entity) {
        return em.merge(entity);
    }

    /**
     * Metodo para persistir un usuario
     *
     * @param user usuario
     * @return usuario persisitido
     */
    public Users persistUsers(Users user) {
        em.persist(user);
        return user;
    }

    /**
     * Metodo para editar/modificar un usuario, si no existe, lo crea
     *
     * @param user usuario
     * @return usuario editado
     */
    public Users mergeUsers(Users user) {
        return em.merge(user);
    }

    /**
     * Metodo para editar/modificar un usuario
     *
     * @param user usuario
     */
    public void refreshUsers(Users user) {
        em.refresh(user);
    }

    /**
     * <code>select o from Users o</code> Metodo para consultar todos los usuario de la capa de persistencia
     *
     * @return lista de usuarios
     */
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<Users> getUsersFindAll() {
        return em.createNamedQuery("Users.findAll", Users.class).getResultList();
    }

    /**
     * Metodo para buscar un usuario por su nombre
     *
     * @param name nombre
     * @return usuario encontrado
     */
    public Users getUser(String name) {
        Users user = null;
        try {
            user = em.createNamedQuery("Users.findByUse", Users.class).setParameter("user", name).getSingleResult();
        } catch (javax.persistence.NoResultException exception) {
            
        }
        return user;
    }

    /**
     * <code>select o from Users o WHERE o.user = :user AND o.password = :pass AND o.active='Y'</code> Metodo para comprobar
     * el login, busca el usuario con usuario y password
     *
     * @param user usuario
     * @param pass password
     * @return lista usuario encontrado
     */
    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<Users> getUsersLogIn(String user, String pass
    ) {      
        return em.createNamedQuery("Users.logIn", Users.class).setParameter("user", user).setParameter("pass",
                pass).getResultList();
    }

    /**
     * Metodo para comprobar si el login ha sido correcto
     *
     * @param user usuario
     * @param pass pass
     * @return cadena de texto con el tipo de usuario o error. ERROR, ADMIN, USER
     */
    @Override
    public String checkLogin(String user, String pass) {
        String enc = "ERROR"; //Si no son correctos los datos
        List<Users> ls = getUsersLogIn(user, pass);
        if (!ls.isEmpty()) {
            if (ls.get(0).getSuperadmin().equals("Y")) {
                enc = "ADMIN"; //Si el usuario es de tipo administrador
            } else {
                enc = "USER"; //Si es un usuario normal
            }
        }
        return enc;
    }
}
